/**
 * 给你一个链表，删除链表的倒数第 n 个结点，并且返回链表的头结点。

进阶：你能尝试使用一趟扫描实现吗？

示例 1：

输入：head = [1,2,3,4,5], n = 2
输出：[1,2,3,5]
示例 2：

输入：head = [1], n = 1
输出：[]
示例 3：

输入：head = [1,2], n = 1
输出：[1]

提示：

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
 */

import { ListNode } from "../dataClass";

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
    let target = null; // 目标指针，指向目标前一个节点
    let end = head; // 结束指针，遍历整个链表
    if (!end) return null;
    // 设定结束指针的起始位置为目标之前的间隔距离
    for (let i = 1; i < n; i++) {
        if (end.next) {
            end = end.next;
        }
    }
    // 遍历链表，结束指针与目标指针同时移动，保持n-1的间隔距离
    while (end.next) {
        end = end.next;
        if (!target) target = head;
        else target = target.next;
    }

    // 删除元素不是链表头
    if (target) {
        // 删除指定节点
        if (target.next && target.next.next) {
            target.next = target.next.next;
        } else {
            // 删除的节点正好是链表尾节点
            target.next = null;
        }
    } else {
        // 删除元素正好是链表头
        head?.next && (head = head.next);
    }
    return head;
}

export { removeNthFromEnd };
